#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>

//#define PATHNAME(number) "log.txt"#number
#define PATHNAME "log.txt"



int main()
{
    close(1);
    int fd = open("log.txt", O_WRONLY | O_CREAT | O_TRUNC,0666);
    if(fd < 0)
    {
        perror("open");
        return 1;
    }

    //dup2(fd, 0); //输入重定向

    char line[64];

    // while(1)
    // {
    //     printf("> "); 
    //     if(fgets(line, sizeof(line), stdin) == NULL) break; //stdin->0
    //     printf("%s", line);
    // }


    printf("open fd: %d\n", fd); // printf -> stdout
    fprintf(stdout, "open fd: %d\n", fd); // printf -> stdout

    // const char *msg= "hello world";
    // write(1, msg, strlen(msg));

    //fflush(stdout);
    close(fd);
    return 0;
}



// //dup2的使用——覆盖fd下标对应的指针
// int main()
// {
//     int fd = open(PATHNAME,O_WRONLY | O_CREAT | O_TRUNC, 0666); //此时fd为3
//     //覆盖stdout所对应的下标的指针
//     //输出重定向
//     dup2(fd,stdout->_fileno); //此时下标1和下标3中的内容，都是指向log.txt的内核数据结构(struct_file)

//     int cnt = 5;
//     char buffer[64];
//     while(cnt)
//     {
//         snprintf(buffer,sizeof(buffer)-1,"hello world:%d\n",cnt--);
//         write(stdout->_fileno,buffer,strlen(buffer)); //写入标准输出中
//     }

//     return 0;
// }



// //fd的本质
// int main()
// {
//     close(stdout->_fileno); //关闭标准输出
//     int fd = open(PATHNAME,O_WRONLY | O_CREAT | O_TRUNC, 0666);
//     int cnt = 5;
//     char buffer[64];
//     while(cnt)
//     {
//         snprintf(buffer,sizeof(buffer)-1,"hello world:%d\n",cnt--);
//         write(stdout->_fileno,buffer,strlen(buffer)); //写入标准输出中
//     }
//     //现象:显示器上没有打印，cat log.txt后，发现本应写入显示器的内容写入到了log.txt中
//     //原因:fd本质是一个struct_file*指针数组的下标，而stdout中的_fileno则对应了数组的1号下标，
//     //当你关闭stdout时，则是将这个下标所对应的指针置null
//     //当你打开log.txt时，log.txt的fd就会选择原本stdout的位置，此时1号下标所对应的指针就指向了log.txt
//     //又由于stdout中的_fileno仍然是1，所以当再次向stdout写入时，其实就变成了向log.txt中写入

//     close(fd);

//     return 0;
// }





// //观察文件描述符
// int main()
// {
//     cout << "stdin->fd:" << stdin->_fileno << endl;
//     cout << "stdout->fd:" << stdout->_fileno << endl;
//     cout << "stderr->fd:" << stderr->_fileno << endl;

//     int fd0 = open(PATHNAME(1), O_WRONLY | O_CREAT | O_APPEND, 0666);
//     int fd1 = open(PATHNAME(2), O_WRONLY | O_CREAT | O_APPEND, 0666);
//     int fd2 = open(PATHNAME(3), O_WRONLY | O_CREAT | O_APPEND, 0666);
//     int fd3 = open(PATHNAME(4), O_WRONLY | O_CREAT | O_APPEND, 0666);
//     int fd4 = open(PATHNAME(5), O_WRONLY | O_CREAT | O_APPEND, 0666);

//     printf("fd: %d\n", fd0);
//     printf("fd: %d\n", fd1);
//     printf("fd: %d\n", fd2);
//     printf("fd: %d\n", fd3);
//     printf("fd: %d\n", fd4);
    
//     close(fd0);
//     close(fd1);
//     close(fd2);
//     close(fd3);
//     close(fd4);

//     return 0;
// }



//系统写操作
// int main()
// {
//     int fd = open(PATHNAME,O_WRONLY | O_CREAT | O_TRUNC,0666);
//     char buffer[1024];
//     int cnt = 5;
//     while(cnt)
//     {
//         snprintf(buffer,sizeof(buffer)-1,"hello world:%d\n",cnt--);
//         write(fd,buffer,strlen(buffer));//不需要写\0,因为\0是语言规定的结束符，不是系统规定的
//     }
//     close(fd);

//     return 0;
// }


//系统读操作
// int main()
// {
//     int fd = open(PATHNAME,O_RDONLY);
//     char buffer[1024];
//     while(1)
//     {
//         int num = read(fd,buffer,sizeof(buffer)-1);
//         if(num <= 0)
//             break;
//         buffer[strlen(buffer)] = 0;
//         cout << buffer;
//     }
//     close(fd);

//     return 0;
// }



// int main()
// {
//     //C语言操作文件
//     FILE* fp = fopen(PATHNAME,"w");
//     //FILE* fp = fopen(PATHNAME,"r");

//     char buffer[1024];
//     int cnt = 5;
//     while(cnt)
//     {
//         snprintf(buffer,sizeof(buffer),"hello world:%d\n",cnt);
//         cnt--;
//         fprintf(fp,buffer);
//     }

//     // while(fgets(buffer,sizeof(buffer)-1,fp) != nullptr)
//     // {
//     //     puts(buffer);
//     // }
    
//     fclose(fp);

//     return 0;
// }